package com.xtm.exercise.utils.uuid;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;

import java.time.Instant;
import java.util.Date;

/**
 * ID生成器工具类
 * 为什么要用雪花算法？
     生成有顺序的id，提高数据库的性能,现在大部分都不用uuid作为主键，因为不规则，每向数据库插入一条数据就要重新排列，使数据库性能降低。
     分布式环境，ID唯一
     所有生成的id按时间趋势递增
 * @author ruoyi
 */
public class IdUtils {

    // 基准时间使用推特的，用这个变量命名
    private static long twepoch = 1288834974657L;

    public static void main(String[] args) {
        String s = idWorkerHutool();

        SnowFlakeUtilV2 snowFlakeUtilV21 = new SnowFlakeUtilV2();
        snowFlakeUtilV21.getSnowflakeId();
        Long nextId = SnowFlakeUtilV2.getNextId();
        System.out.println(nextId); //1788385306045054976
    }
    /**
     * hutool雪花算法
     * https://blog.csdn.net/xiao_san_san/article/details/129969602?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171517322716800211560731%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171517322716800211560731&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-14-129969602-null-null.142^v100^pc_search_result_base8&utm_term=IdUtil.getSnowflake%28&spm=1018.2226.3001.4187
     *
     * @return
     */
    public static String idWorkerHutool(){
        // IdUtil.getSnowflake(1, 1) 表示创建一个雪花算法实例，其中参数 1 和 1 分别表示数据中心ID和机器ID。nextId() 方法用于生成下一个唯一的ID。
        Long workerId = NetUtil.ipv4ToLong(NetUtil.getLocalhostStr()) >> 16 & 31;
        Long dataCenterId = 1L;
        Snowflake snowflake = IdUtil.getSnowflake(workerId, dataCenterId);
//        long id = snowflake.nextId(); // long
        String id = snowflake.nextIdStr(); // string
        return id;
    }

    /**
     * mybatisplus 雪花算法 - 推荐使用
     * @return
     */
    public static String idWorkerStrMybatisplus(){
        String idStr = IdWorker.getIdStr();
        return idStr;
    }

    public static long idWorkerMybatisplus(){
        return IdWorker.getId();
    }

    /**
     * 通过雪花算法id获取日期类型的时间
     * @param idWorkerId
     * @return
     */
    public static Date getDateByIdWorkerId(Long idWorkerId){
        long baseMill = twepoch; // 基准时间
        long mill = (idWorkerId >> 22) + baseMill;
        Date date = Date.from(Instant.ofEpochMilli(mill));
        return date;
    }

    /**
     * 获取随机UUID
     * @return 随机UUID
     */
    public static String randomUUID()
    {
        return IdUtil.randomUUID();
    }

    /**
     * 简化的UUID，去掉了横线
     * 
     * @return 简化的UUID，去掉了横线
     */
    public static String simpleUUID()
    {
        return IdUtil.simpleUUID();
    }

    /**
     * 获取随机UUID，使用性能更好的ThreadLocalRandom生成UUID
     * 
     * @return 随机UUID
     */
    public static String fastUUID()
    {
        return UUID.fastUUID().toString();
    }

    /**
     * 简化的UUID，去掉了横线，使用性能更好的ThreadLocalRandom生成UUID
     * 
     * @return 简化的UUID，去掉了横线
     */
    public static String fastSimpleUUID()
    {
        return UUID.fastUUID().toString(true);
    }
}
